/*
 *
 *   Copyright (C) 2005 by Raymond Huang
 *   plushuang at users.sourceforge.net
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  In addition, as a special exception, the copyright holders give
 *  permission to link the code of portions of this program with the
 *  OpenSSL library under certain conditions as described in each
 *  individual source file, and distribute linked combinations
 *  including the two.
 *  You must obey the GNU Lesser General Public License in all respects
 *  for all of the code used other than OpenSSL.  If you modify
 *  file(s) with this exception, you may extend this exception to your
 *  version of the file(s), but you are not obligated to do so.  If you
 *  do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source
 *  files in the program, then also delete it here.
 *
 */


#include <urlglib/base_node.h>

void  base_node_instance_init     (BaseNode* node)
{
	node->reference_count = 1;
	node->inserted_signal = NULL;
	node->removed_signal  = NULL;
}

void  base_node_instance_finalize (BaseNode* node)
{
	BaseNode*  children;

	// unlink & unref children
	children = base_node_child (node);
	while (children) {
		base_node_unlink (children);
		base_node_unref (children);
		children = base_node_child (node);
	}
	// finalize self
	urlglib_signal_list_free (&node->inserted_signal);
	urlglib_signal_list_free (&node->removed_signal);
	base_node_unlink (node);
}

void  base_node_ref   (BaseNode* node)
{
	node->reference_count++;
}

void  base_node_unref (BaseNode* node)
{
	if (--node->reference_count == 0) {
		node->finalize (node);
		g_free (node);
//		g_message ("base node finalized & freed");
	}
}

void  base_node_insert_before (BaseNode* parent, BaseNode* sibling, BaseNode* node)
{
	g_node_insert_before ((GNode*)parent, (GNode*)sibling, (GNode*)node);
	base_node_inserted (parent, node);
}

void  base_node_insert_after  (BaseNode* parent, BaseNode* sibling, BaseNode* node)
{
	g_node_insert_after ((GNode*)parent, (GNode*)sibling, (GNode*)node);
	base_node_inserted (parent, node);
}

void base_node_append (BaseNode* parent, BaseNode* node)
{
	g_node_append ((GNode*)parent, (GNode*)node);
	base_node_inserted (parent, node);
}

void base_node_prepend (BaseNode* parent, BaseNode* node)
{
	g_node_prepend ((GNode*)parent, (GNode*)node);
	base_node_inserted (parent, node);
}

void base_node_unlink (BaseNode* node)
{
	BaseNode* parent = base_node_parent (node);
	int       position;

	if (parent)
		position = base_node_child_position (parent, node);

	g_node_unlink ((GNode*)node);

	if (parent)
		base_node_removed (parent, node, position);
}

// callback & setup

void base_node_signal_emit_full (GSList** signal_list, BaseNode* parent, BaseNode* child, int nth)
{
	UrlglibSignal*  ug_signal;

	if (*signal_list == NULL)
		return;

	if (nth == -1)
		nth = base_node_child_position (parent, child);

/*
	{                                  
		GList* __list_1;                           
		for (__list_1 = *signal_list; __list_1; __list_1=__list_1->next) {    
			ug_signal = (UrlglibSignal*)__list_1->data;
			((BaseNodeCallback)ug_signal->callback) (parent, child, nth, ug_signal->data);
		}
	}
*/
	URLGLIB_SIGNAL_EMIT_BEG (signal_list, ug_signal);
		((BaseNodeCallback)ug_signal->callback) (parent, child, nth, ug_signal->data);
	URLGLIB_SIGNAL_EMIT_END ();
}
